package it.unibo.mumu;

import it.unibo.mumu.R;
import it.unibo.mumu.entity.Planet;
import it.unibo.mumu.entity.UniverseSelected;
import it.unibo.mumu.util.SingletonSupport;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;

import android.R.color;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Point;
import android.util.DisplayMetrics;
//import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Toast;

public class GalaxyActivity extends Activity {

	public static final boolean DEBUG = false;
	
	private Display display;
	private RelativeLayout container;
	private FrameLayout frame;
	private HintsLayout hintsLayout;
	private int currentX;
	private int currentY;
	private ImageButton changeMoodBtn;
	
	private int realWidth, realHeight; // dimensioni dello schermo
	
	private int tot_width, tot_height; // dimensioni della galassia

	private int universeId;
	
	private ArrayList<SmallPlanet> planets;
	
	private MediaPlayer mp;
	
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		display = getWindowManager().getDefaultDisplay();
		display.getRotation();
		this.obtainScreenSize();
		
		// prendere da intent l'oggetto universe oppure prendere l'id e fare il parsing
		universeId = -1;
		tot_width = 0;
		tot_height = 0;
		setContentView(R.layout.main); // indica il nome del file xml che si
										// occupa del design
		
		container = (RelativeLayout) findViewById(R.id.container);
		frame = (FrameLayout) findViewById(R.id.frame);
		hintsLayout = new HintsLayout(this);
		changeMoodBtn = (ImageButton)findViewById(R.id.changeHappinessButton);
		
		changeMoodBtn.setOnClickListener(getChangeMoodListener());
		
		ImageView image1 = new ImageView(this);
		image1.setImageResource(R.drawable.bg1);
//		Log.i("Img dimension", image1.getDrawable().getIntrinsicWidth() + "x"
//				+ image1.getDrawable().getIntrinsicHeight());
		RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
				1400, 1344);
		layoutParams.leftMargin = tot_width;
		tot_width += 1400;
		tot_height += 1344;
		container.addView(image1, layoutParams);
		
		ImageView image2 = new ImageView(this);
		image2.setImageResource(R.drawable.bg2);
		RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(784, 1344);
		layoutParams1.leftMargin = tot_width;
		tot_width += 784;
		
		container.addView(image2, layoutParams1);
		
		ImageView image3 = new ImageView(this); //
		image3.setImageResource(R.drawable.bg3);
		RelativeLayout.LayoutParams layoutParams2 = new RelativeLayout.LayoutParams(
				1400, 1344);
		layoutParams2.leftMargin = tot_width;
		tot_width += 1400;
		container.addView(image3, layoutParams2);
		
		// inizializzo l'Hints layout
		RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(tot_width, tot_height);
		hintsLayout.setBackgroundColor(color.background_dark);
		hintsLayout.drawHintsFromLastPlanet();
		container.addView(hintsLayout,rlp);
		
		FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(tot_width,
				tot_height);
		frame.setLayoutParams(flp);
		
		universeId = SingletonSupport.getInstance().getUniverseID();
//		Log.i("tmp", "valore: "+String.valueOf(universeId));
		SingletonSupport.getInstance().setRealUniverseID(universeId);
		this.generatePlanets(universeId);
		
		int lastPlanetId = SingletonSupport.getInstance().getLastPlanetVisitedID();
		if(lastPlanetId >= 0){
			Planet lastPlanet = SingletonSupport.getInstance().getUniverses().get(SingletonSupport.getInstance().getRealUniverseID()).getPlanets().get(lastPlanetId);
			container.scrollTo(Math.round(lastPlanet.getCoordX())-realWidth/2, Math.round(lastPlanet.getCoordY()-realHeight/2));
		} else {
			container.scrollTo((tot_width-realWidth)/2, (tot_height-realHeight)/2);			
		}
		checkBounds();
		// suono di sottofondo
		playBgMusic();
	}
	
	public void playBgMusic() {
	    mp = MediaPlayer.create(this,
	            R.raw.intro2);
	    mp.start();
	    mp.setOnCompletionListener(new OnCompletionListener() {

	        @Override
	        public void onCompletion(MediaPlayer mp) {
	            mp.release();
	        }

	    });

	}
	
	@Override
	protected void onPause() {
		mp.pause();
		super.onPause();
	}
	
	@Override
	protected void onResume() {
		mp.start();
		super.onResume();
	}
	
	@Override
	protected void onDestroy() {
		mp.release();
		super.onDestroy();
	}

	private void checkBounds(){
		int currentScrollX = container.getScrollX();
		if (currentScrollX< 0 ) {
			currentScrollX = 0;
		} else if(currentScrollX > tot_width - realWidth){
			currentScrollX = tot_width - realWidth;
		}
		int currentScrollY = container.getScrollY();
		if (currentScrollY < 0 ) {
			currentScrollY = 0;
		}else if(currentScrollY > tot_height - realHeight){
			currentScrollY = tot_height - realHeight;
		}
		
		container.scrollTo(currentScrollX, currentScrollY);
	}

	@Override
	protected void onStart() {
		super.onStart();
		Iterator<SmallPlanet> i = planets.iterator();
		SmallPlanet currentPlanet;
		while(i.hasNext()){
			currentPlanet = i.next();
			RelativeLayout.LayoutParams l = (LayoutParams) currentPlanet.getLayoutParams();
			l.topMargin += currentPlanet.getScreenH()/2;
			l.leftMargin += currentPlanet.getScreenW()/2;
		}
	}
	
	public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuItem item = menu.add(Menu.NONE, R.id.action_flip, Menu.NONE, R.string.action_back);
        item.setIcon( R.drawable.ic_action_info);
        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        return true;
    }
	
	public boolean onOptionsItemSelected(MenuItem item) {
		
		if(item.getItemId() == R.id.action_flip){
			
				ArrayList<UniverseSelected> universeList = SingletonSupport.getInstance().getUniverses();
				UniverseSelected universe = universeList.get(SingletonSupport.getInstance().getRealUniverseID());
				
				
	        	Intent toInfo = new Intent(GalaxyActivity.this, InfoActivity.class);
	        	toInfo.putExtra("TITLE", "Informazioni sul pianeta");
	        	toInfo.putExtra("TEXT", universe.getDescription());
//				toPlanet.putExtra("PLANET_ID", ps.getIdPlanet());
//	        	System.gc();
//	        	finish();
				startActivity(toInfo);
	        
        }
        return super.onOptionsItemSelected(item);
    }
	
	@Override
	public void onBackPressed() {
		Intent toHome = new Intent(GalaxyActivity.this,
				StartActivity.class);
		// TODO: settare a null lastVisitedPlanet
		SingletonSupport.getInstance().setLastPlanetVisitedID(-99);
		System.gc();
		finish();
		startActivity(toHome);
	}
	
	@SuppressLint("NewApi")
	private void obtainScreenSize() {
		final DisplayMetrics metrics = new DisplayMetrics();
		Method mGetRawH = null, mGetRawW = null;
		if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
			display.getRealMetrics(metrics);
			realWidth = metrics.widthPixels;
			realHeight = metrics.heightPixels;
		} else {
			try {
				mGetRawH = Display.class.getMethod("getRawHeight");
				mGetRawW = Display.class.getMethod("getRawWidth");

				realWidth = (Integer) mGetRawW.invoke(display);
				realHeight = (Integer) mGetRawH.invoke(display);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e1) {
				e1.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}

	}

	private void generatePlanets(int universeId) {
		planets = new ArrayList<SmallPlanet>();
		// TODO: parsing xml
		SingletonSupport support = SingletonSupport.getInstance();
		ArrayList<UniverseSelected> universeList = support.getUniverses();
		
		UniverseSelected selectedUniverse = null;
		for(int i=0; i<universeList.size(); i++){
			if(universeList.get(i).getId() == universeId){
				selectedUniverse = universeList.get(i);
				break;
			}
		}
		
		if(selectedUniverse != null || DEBUG){
			
			SmallPlanet planet;
			ArrayList<Planet> planetList;
			if(DEBUG){
				planetList = new ArrayList<Planet>();
				Planet p;
				for(int i = 0; i < 3; i++){
					p = new Planet();
					p.setIdPlanet(i);
					p.setNamePlanet("Pianeta "+i);
					p.setCoordX(200+i*130);
					p.setCoordY(300+i*190);
					planetList.add(p);
				}
			}else{
				planetList = selectedUniverse.getPlanets();
			}
			
			for(int i = 0; i < planetList.size(); i++){
				int x = Math.round(planetList.get(i).getCoordX());
				int y = Math.round(planetList.get(i).getCoordY());
				planet = new SmallPlanet(this, planetList.get(i).getIdPlanet(),planetList.get(i).getNamePlanet(), new Point(x,y));
				RelativeLayout.LayoutParams flp = new RelativeLayout.LayoutParams(
						RelativeLayout.LayoutParams.WRAP_CONTENT,
						RelativeLayout.LayoutParams.WRAP_CONTENT);
				
				float widthOffset = (100.f/1197.f);
				float heightOffset = (100.f/470.f);
				float normalizedW = 1-((planetList.get(i).getCoordX() / 1984.f) - widthOffset);
				float normalizedH = 1-((planetList.get(i).getCoordY() / 630.f) - heightOffset);
				float opW = tot_width*0.9f*(normalizedW+widthOffset);
				float opH = tot_height*0.75f*(normalizedH+heightOffset)-100;
				planet.setPosition(new Point(Math.round(opW), Math.round(opH)));
				planetList.get(i).setCanvasCoordX(opW);
				planetList.get(i).setCanvasCoordY(opH);
				
				flp.topMargin = planet.getPosition().y;//y
				flp.leftMargin = planet.getPosition().x;//x
				planet.setOnClickListener(getNewPlanetListener());
				planets.add(planet);
				container.addView(planet, flp);
			}
		}
	}

	private View.OnClickListener getNewPlanetListener(){
		View.OnClickListener listener = new View.OnClickListener() {
			public void onClick(View v) {
				SmallPlanet ps = (SmallPlanet)v;
				// container.scrollTo(0, 0);
//				Toast.makeText(
//						getApplicationContext(),
//						"Cliccato " + ps.getLabelText() + " con id: " + ps.getIdPlanet(), Toast.LENGTH_SHORT).show();
				Intent toPlanet = new Intent(GalaxyActivity.this, PlanetDetailActivity.class);
				SingletonSupport.getInstance().setPlanetID(ps.getIdPlanet());

				System.gc();
	        	finish();
				startActivity(toPlanet);
			}
		};
		return listener;
	}
	
	private View.OnClickListener getChangeMoodListener(){
		View.OnClickListener listener = new View.OnClickListener() {
			public void onClick(View v) {
				String textMood;
				if(SingletonSupport.getInstance().isHappiness()){ // era felice lo setto a triste
					SingletonSupport.getInstance().setHappiness(false);
					textMood = "triste";
				}
				else { // era triste lo setto a felice
					SingletonSupport.getInstance().setHappiness(true);
					textMood = "felice";
				}
				
				Toast.makeText(
						getApplicationContext(),
						"Hai cambiato lo stato dell'universo in " + textMood +"!", Toast.LENGTH_SHORT).show();
			}
		};
		return listener;
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN: {
			currentX = (int) event.getRawX();
			currentY = (int) event.getRawY();
			break;
		}

		case MotionEvent.ACTION_MOVE: {
			int x2 = (int) event.getRawX();
			int y2 = (int) event.getRawY();
			int nextScrollX = currentX - x2;
			int nextScrollY = currentY - y2;

//			Log.i("screen", "w:" + realWidth + " , h:" + realHeight);

			if (container.getScrollX() + nextScrollX < 0
					|| container.getScrollX() + nextScrollX > tot_width
							- realWidth) {
				nextScrollX = 0;
				// if(container.getScrollX() > 0 && container.getScrollX() <
				// tot_width-realWidth &&
				// container.getScrollY() > 0 && container.getScrollY() <
				// tot_height-realHeight)
				// v.vibrate(30);
			}

			if (container.getScrollY() + nextScrollY < 0
					|| container.getScrollY() + nextScrollY > tot_height
							- realHeight) {
				nextScrollY = 0;
				// if(container.getScrollX() > 0 && container.getScrollX() <
				// tot_width-realWidth &&
				// container.getScrollY() > 0 && container.getScrollY() <
				// tot_height-realHeight)
				// v.vibrate(30);
			}

			container.scrollBy(nextScrollX, nextScrollY);
			currentX = x2;
			currentY = y2;

//			Log.i("currentPos", container.getScrollX() + " - " + container.getScrollY());

			break;
		}
		case MotionEvent.ACTION_UP: {
			break;
		}
		}
		return true;
	}
}
